home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BBS in a Box 7
/
BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso
/
Files
/
Tele
/
C
/
Comet2.1.3.cpt
/
emlib
/
printf.c
< prev
next >
Wrap
Text File
|
1991-10-28
|
6KB
|
269 lines
/* Copyright 1984 by the Massachusetts Institute of Technology */
/* See permission and disclaimer notice in file "notice.h" */
/*
Copyright Cornell University 1986. All rights are reserved.
As of 4/10/86:
This source file may have no changes from the M.I.T original
other than this notice; but it has been tested as part of
Cornell's Aztec-C port. See notice.h
*/
/* 9/19/85 kevin - putc() changed to em(); all routine(char, outarg) */
/* 9/20/85 kevin added TRUE & FALSE */
/* 9/20/85 kevin changed for 1-parameter em(char) */
/* 9/2/87 kevin changed some names to make new compiler happy */
/* 9/30/87 kevin removed call to Button() in printf which made mouse menu selects difficult when lots of data being rec'd */
/* 3/18/88 kevin fixed so no \r added if output routine not em() */
/* 3/16/89 kevin fixed to use cu_exit() */
/* 9/26/90 kevin changed em to vt100 */
#include <h19.h>
#include <stdio.h>
#define TRUE (-1)
#define FALSE 0
#define DOEMOUTPUT
#ifdef DOEMOUTPUT
extern vt100();
#undef putchar
putchar(thechar)
char thechar;
{
emprep();
vt100(thechar);
emend();
}
printf(format)
char *format;
{
emprep();
_format_string(vt100, stdout, &format); /* kevin was putc */
/* 9/20/86 kevin update cursor if done */
setcursor();
emend();
}
fatal(format)
char *format;
{
emprep();
_format_string(vt100, stdout, &format); /* was putc */
printf("\n");
emend();
cu_exit(1);
}
#endif
#ifdef REDIRECTABLE
fprintf(fd, format)
FILE *fd;
char *format;
{
_format_string(vt100, fd, &format); /* was putc */
}
#endif
int store_string();
char *_sp; /* this should be not be static since it */
/* is used by TCP's printf and others */
sprintf(s, format)
char *s;
char *format;
{
_sp = s;
_format_string(store_string, NULL, &format);
*_sp = '\0';
}
store_string(c) /* was (c, foo); int foo;*/
char c;
{
*_sp++ = c;
}
/* WARNING--kevin-- this routine will break if char != int on the stack */
_format_string(routine, outarg, data)
int (*routine)(); /* the routine to output the characters */
FILE * outarg; /* an argument to pass to the output routine */
char **data; /* the address to get the format string and the arguments from */
{
unsigned *arg; /* a pointer to the arguments on the stack */
char *format; /* a pointer to the format string */
int field; /* number after a '%' and before the format character */
int l_zero; /* flag is true if the number started with a
'0', if so then print out leading zeros */
char *s; /* string pointer for 2nd-nth arguments */
format = *data;
arg = (unsigned *) data;
arg += 2; /* skip first arg, pointer to format string */
loop: while ((*format != '%') && (*format != '\0')) {
/* was (*routine)(*format++, outarg); */
#ifdef DOEMOUTPUT
if (*format == LF && routine == vt100)
/* add CR to LF for emulator */
(*routine)(CR);
#endif
(*routine)(*format++);
}
if (*format == '\0')
return(0);
format++;
if (*format == '0')
l_zero = TRUE;
else
l_zero = FALSE;
field = 0;
while (*format >= '0' && *format <= '9') {
field = field * 10 + *format - '0';
format++;
}
switch (*format) {
case 's':
s = *(char **)arg;
while (*s != '\0')
/* was (*routine)(*s++, outarg); */
(*routine)(*s++);
arg += 2;
break;
case 'c':
/* was (*routine)(*(char *)arg, outarg); */
(*routine)(*arg);
arg++;
break;
case '%':
/* was (*routine)('%', outarg); */
(*routine)('%');
arg++;
break;
case 'o':
int_print((unsigned long)*arg, 010, FALSE, field, l_zero, routine, outarg);
arg++;
break;
case 'O':
int_print(*(unsigned long *)arg, 010, FALSE, field, l_zero, routine, outarg);
arg += 2;
break;
case 'd':
int_print((long)*(int *)arg, 10, TRUE, field, l_zero, routine, outarg);
arg++;
break;
case 'D':
int_print(*(long *)arg, 10, TRUE, field, l_zero, routine, outarg);
arg += 2;
break;
case 'u':
int_print((unsigned long)*arg, 10, FALSE, field, l_zero, routine, outarg);
arg++;
break;
case 'U':
int_print(*(unsigned long *)arg, 10, FALSE, field, l_zero, routine, outarg);
arg += 2;
break;
case 'x':
int_print((unsigned long)*arg, 0x10, FALSE, field, l_zero, routine, outarg);
arg++;
break;
case 'X':
int_print(*(unsigned long *)arg, 0x10, FALSE, field, l_zero, routine, outarg);
arg += 2;
break;
#define mkbyte(x) (((unsigned)(x))&0xff)
case 'a': {
union {
long _l;
char _c[4];
} foo;
foo._l = *(long *)arg;
arg += 2;
_pr_ip(routine, outarg, "%d.%d.%d.%d",
mkbyte(foo._c[0]), mkbyte(foo._c[1]),
mkbyte(foo._c[2]), mkbyte(foo._c[3]));
}
break;
case 'A': {
union {
long _l;
char _c[4];
} foo;
foo._l = *(long *)arg;
arg += 2;
_pr_ip(routine, outarg, "%o,%o,%o,%o",
mkbyte(foo._c[0]), mkbyte(foo._c[1]),
mkbyte(foo._c[2]), mkbyte(foo._c[3]));
}
break;
}
format++;
goto loop;
}
int_print(number, radix, hassign, field, l_zero, routine, outarg)
unsigned long number; /* the number to print */
int radix; /* the radix to print the number in */
int hassign; /* true if should print as signed number */
int field; /* the argument in the format control */
int l_zero; /* true if arg had a leading zero */
int (*routine)(); /* routine to print out the number */
int outarg; /* an argument to pass to the output routine */
{
char table[20]; /* place to make up the output */
int negative; /* true if number is signed and negative */
int i;
char c;
if (hassign && ((long)number < 0)) {
negative = TRUE;
number = -(long)number;
}
else negative = FALSE;
c = l_zero ? '0' : ' ';
for (i=0; i < 20; i++)
table[i] = c;
for (i = 0; i < 20; i++) {
table[i] = "0123456789ABCDEF"[number % (long)radix];
number /= (long)radix;
if (number == 0) break;
}
if (negative) table[++i] = '-';
if ((field != 0) && (field < 20)) i = field - 1;
while (i >= 0)
/* was (*routine)(table[i--], outarg); */
(*routine)(table[i--]);
}
_pr_ip(routine, outarg, format)
char *outarg;
int (*routine)();
char *format;
{
_format_string(routine, outarg, &format);
}